/*
 * ringbuf.c
 * 环形缓冲区实现 - 已修改适配live555框架
 * 主要变更：
 * 1. 添加了HisiPutH264DataToBuffer函数适配君正T32平台编码器
 * 2. 移除了对UpdateSps和UpdatePps函数的调用，因为Live555框架会自动处理SPS/PPS
 * 3. 优化了缓冲区管理，添加了更详细的注释
 * 用于在live555 RTSP流媒体传输中管理编码后的视频数据
 */

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>  // 添加stdbool.h以支持bool类型
#include "ringfifo.h"  // 包含环形缓冲区头文件
#include <pthread.h>
#include "../service/VideoLogger.h"  // 使用统一的日志系统

// 定义IMPEncoderDataType联合体（SDK官方定义）
typedef union {
    int type;              // 通用类型字段
} IMPEncoderDataType;

// 定义IMPRefType枚举（SDK官方定义）
typedef enum {
    IMP_REF_TYPE_UNKNOW = 0,  // 未知类型
    IMP_REF_TYPE_I,           // I帧
    IMP_REF_TYPE_P,           // P帧
    IMP_REF_TYPE_B,           // B帧
    IMP_REF_TYPE_BUTT         // 结束标记
} IMPRefType;

// 定义IMPEncoderPack结构体（与SDK官方定义完全一致）
typedef struct {
    uint32_t    phyAddr;           /**< 码流包物理地址 */
    uint32_t    virAddr;           /**< 码流包虚拟地址 */
    uint32_t    length;            /**< 码流包长度 */
    int64_t     timestamp;         /**< 时间戳，单位us */
    bool        frameEnd;          /**< 帧结束标识 */
    IMPEncoderDataType dataType;   /**< H.264和H.265编码Channel码流NAL类型 */
} IMPEncoderPack;

// 定义IMPEncoderStream结构体（与SDK官方定义完全一致）
typedef struct {
    IMPEncoderPack  *pack;         /**< 帧码流包结构 */
    uint32_t        packCount;     /**< 一帧码流的所有包的个数 */
    uint32_t        seq;           /**< 编码帧码流序列号 */
    IMPRefType      refType;       /**< 编码帧参考类型, 只针对H264和h265 */
} IMPEncoderStream;
#define NMAX 64  // 环形缓冲区的最大容量，可容纳64个数据帧（与RTSP正确实现保持一致）

// 全局变量，用于环形缓冲区管理
int iput = 0; /* 写入位置索引 */
int iget = 0; /* 读取位置索引 */
int n = 0;    /* 当前缓冲区中数据帧的数量 */

// 环形缓冲区数组，存储多个数据帧
ringbuf ringfifo[NMAX];

// 全局变量：记录已分配的缓冲区大小，用于避免重复分配
static int g_allocated_size = 0;

// 全局变量：标记环形缓冲区是否已正确初始化
static bool g_ring_buffer_initialized = false;

// 全局互斥锁，用于保护环形缓冲区的访问
static pthread_mutex_t g_ring_mutex = PTHREAD_MUTEX_INITIALIZER;

/**************************************************************************************************
** ringfifo_is_initialized - 检查环形缓冲区是否已初始化
** 返回值：
**   1 - 已初始化
**   0 - 未初始化
**************************************************************************************************/
int ringfifo_is_initialized(void)
{
    return g_ring_buffer_initialized ? 1 : 0;
}

// 内部函数声明
static void ringfree_internal(void);

// 外部函数声明 - 原始代码中的函数，在live555版本中实际未使用
// 外部函数声明 - 原始代码中的函数，在live555版本中实际未使用
extern int UpdateSpsOrPps(unsigned char *data, int frame_type, int len);

// 辅助函数：获取当前环形缓冲区单帧容量
static inline int ringbuffer_capacity(void)
{
    return g_allocated_size;
}

// 注意：在原始RTSP代码中，这里还声明了UpdateSps和UpdatePps函数
// 在live555版本中已移除这些声明，因为Live555框架会自动处理H.264参数集

/* 
 * ringmalloc - 初始化环形缓冲区，为每个缓冲区分配内存
 * 参数：
 *   size - 每个缓冲区的大小（字节）
 * 功能：
 *   为环形缓冲区中的每个元素分配指定大小的内存空间，并初始化相关参数
 *   索引从0到NMAX-1循环
 */
void ringmalloc(int size)
{
    pthread_mutex_lock(&g_ring_mutex);

    // 参数有效性检查：确保 size 在合理范围内
    if (size <= 0) {
        ringfifo_log_error("ringmalloc: Invalid size parameter: %d (must be > 0)", size);
        pthread_mutex_unlock(&g_ring_mutex);
        return;
    }
    
    // 检查 size 是否过小（小于 1KB 可能是错误的）
    if (size < 1024) {
        ringfifo_log_warning("ringmalloc: Size %d is very small (< 1KB), this may be an error. Using minimum 1MB instead.", size);
        size = 1024 * 1024;  // 使用最小 1MB
    }
    
    // 检查 size 是否过大（超过 100MB 可能是错误的）
    if (size > 100 * 1024 * 1024) {
        ringfifo_log_warning("ringmalloc: Size %d is very large (> 100MB), limiting to 100MB.", size);
        size = 100 * 1024 * 1024;  // 限制为 100MB
    }
    
    // 检查是否已经分配了缓冲区，且大小相同，则不需要重新分配（与RTSP正确实现保持一致）
    int already_allocated = 0;
    for(int i = 0; i < NMAX; i++) {
        if(ringfifo[i].buffer != NULL) {
            already_allocated = 1;
            break;
        }
    }
    
    // 如果已分配且大小相同，直接返回（避免重复分配导致的问题）
    if(already_allocated && g_allocated_size == size) {
        ringfifo_log_info("ringmalloc: Buffers already allocated with same size %d, skipping reallocation", size);
        pthread_mutex_unlock(&g_ring_mutex);
        return;
    }
    
    // 如果已分配但大小不同，需要先释放
    if(already_allocated) {
        ringfifo_log_warning("ringmalloc: Buffers already allocated with size %d, requested size %d, freeing existing buffers first", 
               g_allocated_size, size);
        ringfree_internal();  // 释放已分配的缓冲区
    }
    
    ringfifo_log_info("ringmalloc: Allocating %d buffers of size %d bytes each (total: %d KB)", 
           NMAX, size, (NMAX * size) / 1024);
    
    for(int i = 0; i < NMAX; i++)
    {
        if(ringfifo[i].buffer != NULL) {
            ringfifo_log_warning("ringmalloc: buffer[%d] is not NULL before allocation, clearing existing memory", i);
            free(ringfifo[i].buffer);
            ringfifo[i].buffer = NULL;
        }
        
        // 为每个缓冲区分配内存
        // 使用 malloc 分配内存，malloc 保证返回的地址是正确对齐的（至少对齐到 sizeof(void*)）
        ringfifo[i].buffer = (unsigned char*)malloc(size);
        // 检查分配是否成功
        if(ringfifo[i].buffer == NULL)
        {
            ringfifo_log_error("ringmalloc: Failed to allocate buffer[%d] of size %d (total allocated so far: %d)", 
                   i, size, i);
            // 如果分配失败，释放已分配的缓冲区并退出
            for(int j = 0; j < i; j++)
            {
                if(ringfifo[j].buffer != NULL) {
                    free(ringfifo[j].buffer);
                    ringfifo[j].buffer = NULL;
                }
                ringfifo[j].size = 0;
                ringfifo[j].frame_type = 0;
            }
            iput = 0;
            iget = 0;
            n = 0;
            g_allocated_size = 0;
            pthread_mutex_unlock(&g_ring_mutex);
            return;
        }
        
        // 防御性初始化：确保新分配的缓冲区指针和属性有效
        if(ringfifo[i].buffer == NULL)
        {
            ringfifo_log_error("ringmalloc: Buffer %d allocation verification failed", i);
            // 释放已经分配的缓冲区
            for(int j = 0; j < i; j++)
            {
                if(ringfifo[j].buffer != NULL) {
                    free(ringfifo[j].buffer);
                    ringfifo[j].buffer = NULL;
                }
            }
            iput = 0;
            iget = 0;
            n = 0;
            g_allocated_size = 0;
            pthread_mutex_unlock(&g_ring_mutex);
            return;
        }
        
        // 初始化缓冲区大小为0
        ringfifo[i].size = 0;
        // 初始化帧类型为0
        ringfifo[i].frame_type = 0;
    }
    // 重置索引和计数器
    iput = 0; 
    iget = 0; 
    n = 0; 
    
    // 记录已分配的大小
    g_allocated_size = size;
    
    // 标记环形缓冲区已成功初始化
    g_ring_buffer_initialized = true;
    
    ringfifo_log_info("ringmalloc: Successfully allocated %d buffers, g_ring_buffer_initialized = %d", NMAX, g_ring_buffer_initialized);
    pthread_mutex_unlock(&g_ring_mutex);
}

/**************************************************************************************************
** ringreset - 重置环形缓冲区
** 功能：
**   将写入索引、读取索引和帧计数器重置为初始状态
**   注意：此函数不会释放已分配的内存
**************************************************************************************************/
void ringreset()
{
    pthread_mutex_lock(&g_ring_mutex);
    iput = 0; /* 重置写入位置索引 */
    iget = 0; /* 重置读取位置索引 */
    n = 0;    /* 重置缓冲区中数据帧的数量 */
    pthread_mutex_unlock(&g_ring_mutex);
}

/**************************************************************************************************
** ringfree_internal - 内部释放实现（调用方需保证已加锁）
**************************************************************************************************/
static void ringfree_internal(void)
{
    for(int i = 0; i < NMAX; i++)
    {
        // 防御性释放：只释放非NULL指针
        if(ringfifo[i].buffer != NULL) {
            free(ringfifo[i].buffer);
            // 确保指针被设置为NULL，防止悬垂指针
            ringfifo[i].buffer = NULL;
        }
        // 重置缓冲区属性
        ringfifo[i].size = 0;
        ringfifo[i].frame_type = 0;
    }
    // 重置所有状态变量
    iput = 0;
    iget = 0;
    n = 0;
    g_allocated_size = 0;
    // 重置初始化状态标志
    g_ring_buffer_initialized = false;
    ringfifo_log_info("ringfree_internal: All buffers freed successfully, g_ring_buffer_initialized = %d", g_ring_buffer_initialized);
}

/**************************************************************************************************
** ringfree - 释放环形缓冲区的所有内存
** 功能：
**   释放环形缓冲区中每个元素的内存，并重置相关参数
**************************************************************************************************/
void ringfree(void)
{
    pthread_mutex_lock(&g_ring_mutex);
    ringfifo_log_info("begin free mem");
    ringfree_internal();
    pthread_mutex_unlock(&g_ring_mutex);
}

/**************************************************************************************************
** addring - 计算环形缓冲区的下一个索引位置
** 参数：
**   i - 当前索引
** 返回值：
**   下一个索引位置
** 功能：
**   实现环形缓冲区的循环索引计算，当达到最大值NMAX时，返回0
**************************************************************************************************/
int addring(int i)
{
    // 增强参数有效性检查，防止传入非法索引值
    if (i < 0 || i >= NMAX)
    {
        ringfifo_log_error("addring: invalid index %d (must be between 0 and %d)", i, NMAX-1);
        // 返回安全的默认值
        return 0;
    }
    
    return (i+1) == NMAX ? 0 : i+1;
}

/**************************************************************************************************
** ringget - 从环形缓冲区中获取一个数据帧
** 参数：
**   getinfo - 用于存储获取的数据帧信息的结构体指针
** 返回值：
**   获取的数据帧大小（字节），如果缓冲区为空则返回0
** 功能：
**   从读取位置获取一个数据帧，并更新读取索引和帧计数器
**************************************************************************************************/
int ringget(ringbuf *getinfo)
{
    int result = 0;
    
    // 增强参数有效性检查
    if (getinfo == NULL)
    {
        ringfifo_log_error("ringget: getinfo parameter is NULL");
        return -1;
    }
    
    // 检查环形缓冲区是否已正确初始化
    if (!g_ring_buffer_initialized)
    {
        ringfifo_log_error("ringget: Ring buffer not initialized! Call ringmalloc first");
        return 0;
    }
    
    pthread_mutex_lock(&g_ring_mutex);

    if(n > 0)
    {
        int Pos = iget;
        
        // 验证读取位置的缓冲区是否有效
        if (Pos < 0 || Pos >= NMAX)
        {
            ringfifo_log_error("ringget: invalid buffer position %d", Pos);
            pthread_mutex_unlock(&g_ring_mutex);
            return -1;
        }
        
        // 验证ringfifo[Pos].buffer是否有效
        if (ringfifo[Pos].buffer == NULL)
        {
            ringfifo_log_error("ringget: ringfifo[%d].buffer is NULL", Pos);
            pthread_mutex_unlock(&g_ring_mutex);
            return -1;
        }
        
        // 更新读取位置和帧计数器
        iget = addring(iget);
        n--;
        
        // 安全地复制数据到getinfo，添加额外的安全检查
        // 确保不会返回指向无效地址的buffer
        if ((uintptr_t)ringfifo[Pos].buffer >= 0x1000) { // 确保地址不是低地址
            getinfo->buffer = ringfifo[Pos].buffer;
            getinfo->frame_type = ringfifo[Pos].frame_type;
            getinfo->size = ringfifo[Pos].size;
            result = ringfifo[Pos].size;
        } else {
            // 地址看起来无效，将所有字段设置为安全值
            getinfo->buffer = NULL;
            getinfo->frame_type = 0;
            getinfo->size = 0;
            result = 0;
            ringfifo_log_warning("ringget: Detected potentially invalid buffer address %p at position %d", 
                   ringfifo[Pos].buffer, Pos);
        }
    }
    else
    {
        // 缓冲区为空时，清空getinfo的内容
        getinfo->buffer = NULL;
        getinfo->frame_type = 0;
        getinfo->size = 0;
        result = 0;
    }

    pthread_mutex_unlock(&g_ring_mutex);
    return result;
}

/**************************************************************************************************
** ringput - 向环形缓冲区中写入一个数据帧
** 参数：
**   buffer - 要写入的数据指针
**   size - 数据大小（字节）
**   encode_type - 编码类型
** 功能：
**   将数据写入到当前写入位置，并更新写入索引和帧计数器
**   如果缓冲区已满，则丢弃数据
**************************************************************************************************/
void ringput(unsigned char *buffer, int size, int encode_type)
{
    // 增强参数有效性检查
    if (buffer == NULL || buffer == 0)
    {
        ringfifo_log_error("ringput: buffer parameter is NULL");
        return;
    }
    
    if (size <= 0 || size > 1024*1024)
    {
        ringfifo_log_error("ringput: invalid size parameter: %d", size);
        return;
    }
    
    // 检查环形缓冲区是否已正确初始化
    if (!g_ring_buffer_initialized)
    {
        ringfifo_log_error("ringput: Ring buffer not initialized! Call ringmalloc first");
        return;
    }
    
    pthread_mutex_lock(&g_ring_mutex);

    if(n < NMAX)
    {
        // 验证写入位置是否有效
        if (iput < 0 || iput >= NMAX)
        {
            ringfifo_log_error("ringput: invalid buffer position %d", iput);
            pthread_mutex_unlock(&g_ring_mutex);
            return;
        }
        
        // 验证目标缓冲区是否有效
        if(ringfifo[iput].buffer == NULL)
        {
            ringfifo_log_error("ringput: ringfifo[%d].buffer is NULL, data dropped", iput);
            pthread_mutex_unlock(&g_ring_mutex);
            return;
        }
        
        // 验证g_allocated_size是否有效
        if (g_allocated_size <= 0)
        {
            ringfifo_log_error("ringput: g_allocated_size is invalid (%d), ringmalloc not called", g_allocated_size);
            pthread_mutex_unlock(&g_ring_mutex);
            return;
        }
        
        // 防止缓冲区溢出
        if (size > g_allocated_size)
        {
            ringfifo_log_error("ringput: data size (%d) exceeds buffer capacity (%d)", size, g_allocated_size);
            pthread_mutex_unlock(&g_ring_mutex);
            return;
        }

        // 保存目标指针到局部变量，避免重复访问共享数据结构
        unsigned char *target_buffer = ringfifo[iput].buffer;
        if (target_buffer == NULL)
        {
            ringfifo_log_error("ringput: target_buffer became NULL after assignment");
            pthread_mutex_unlock(&g_ring_mutex);
            return;
        }
        
        // 进行安全的内存复制
        memcpy(target_buffer, buffer, size);
        
        // 更新缓冲区信息
        ringfifo[iput].size = size;
        ringfifo[iput].frame_type = encode_type;
        
        // 更新写入位置和帧计数器
        iput = addring(iput);
        n++;
    }
    else
    {
        ringfifo_log_warning("ringput: buffer is full, data dropped");
    }

    pthread_mutex_unlock(&g_ring_mutex);
}

/**************************************************************************************************
** HisiPutH264DataToBuffer - 将编码器的H.264数据写入环形缓冲区
** 参数：
**   stream - 编码器流结构体指针，包含编码后的视频数据
** 返回值：
**   0 - 成功，-1 - 失败
** 功能：
**   处理编码器输出的H.264数据，支持多包数据的拼接
**   自动识别并更新SPS/PPS参数集
**   丢弃过大的帧数据
**************************************************************************************************/

// 向环形缓冲区写入H.264数据的通用函数
int putH264DataToBuffer(unsigned char* data, size_t length)
{
    int ret = 0;

    // 严格的输入参数验证
    if (!data || data == 0 || length <= 0)
    {
        ringfifo_log_error("putH264DataToBuffer: invalid input parameters (data=%p, length=%zu)", data, length);
        return -1;
    }
    
    // 检查数据长度是否超过限制
    if(length >= 1024*1024)
    {
        ringfifo_log_error("putH264DataToBuffer: dropping oversized data (%zu bytes)", length);
        return 1;
    }
    
    // 检查环形缓冲区是否已正确初始化
    if (!g_ring_buffer_initialized)
    {
        ringfifo_log_error("putH264DataToBuffer: Ring buffer not initialized! Call ringmalloc first");
        return -1;
    }

    pthread_mutex_lock(&g_ring_mutex);

    if(n < NMAX)
    {
        // 严格检查目标缓冲区是否有效
        if(ringfifo[iput].buffer == NULL)
        {
            ringfifo_log_error("putH264DataToBuffer: ringfifo[%d].buffer is NULL, data dropped", iput);
            pthread_mutex_unlock(&g_ring_mutex);
            return -1;
        }
        
        // 检查g_allocated_size是否有效
        if (g_allocated_size <= 0 || g_allocated_size < length)
        {
            ringfifo_log_error("putH264DataToBuffer: g_allocated_size invalid (%d) or less than data length (%zu)", 
                   g_allocated_size, length);
            pthread_mutex_unlock(&g_ring_mutex);
            return -1;
        }

        // 保存目标指针到局部变量，避免重复访问共享数据结构
        unsigned char *target_buffer = ringfifo[iput].buffer;
        if (target_buffer == NULL)
        {
            ringfifo_log_error("putH264DataToBuffer: target_buffer became NULL after assignment");
            pthread_mutex_unlock(&g_ring_mutex);
            return -1;
        }
        
        // 进行安全的内存复制前的最终检查
        if (target_buffer == NULL || data == NULL || data == 0 || length == 0 || g_allocated_size <= 0)
        {
            ringfifo_log_error("putH264DataToBuffer: final validation failed before memcpy");
            pthread_mutex_unlock(&g_ring_mutex);
            return -1;
        }
        
        // 进行安全的内存复制
        memcpy(target_buffer, data, length);
        // 检查H.264 NAL类型（支持3字节和4字节起始码）
        int iframe = 0;
        for(size_t i = 0; i + 4 <= length; i++) {
            int nal_type = 0;
            if(i + 5 <= length && data[i] == 0x00 && data[i+1] == 0x00 && data[i+2] == 0x00 && data[i+3] == 0x01) {
                nal_type = data[i+4] & 0x1F;
            } else if(i + 4 <= length && data[i] == 0x00 && data[i+1] == 0x00 && data[i+2] == 0x01) {
                nal_type = data[i+3] & 0x1F;
            } else {
                continue;
            }

            if(nal_type == 7) {
                iframe = 1;
                ringfifo_log_debug("Found SPS: nal_type=%d", nal_type);
                break;
            }
            if(nal_type == 8) {
                ringfifo_log_debug("Found PPS: nal_type=%d", nal_type);
            }
            if(nal_type == 5) {
                iframe = 1;
                ringfifo_log_debug("Found IDR frame: nal_type=%d", nal_type);
                break;
            }
        }

        ringfifo[iput].size = length;
        ringfifo[iput].frame_type = iframe;
        iput = addring(iput);
        n++;
        ret = 0;
    }
    else {
        ringfifo_log_warning("Buffer is full, data dropped");
        ret = -2;
    }

    pthread_mutex_unlock(&g_ring_mutex);
    return ret;
}

/**************************************************************************************************
** HisiPutH264DataToBuffer - 将编码器的H.264数据写入环形缓冲区
** 参数：
**   stream - 编码器流结构体指针，包含编码后的视频数据
** 返回值：
**   1 - 成功，0 - 失败
** 功能：
**   处理编码器输出的H.264数据，支持多包数据的拼接
**   自动识别并更新SPS/PPS参数集
**   丢弃过大的帧数据
**************************************************************************************************/
int HisiPutH264DataToBuffer(void *stream)
{
    int i;
    int len = 0, off = 0;
    int iframe = 0; // 标识是否为I帧
    IMPEncoderStream *encoderStream = (IMPEncoderStream *)stream;
    
    // 1. 增强参数有效性检查
    if (encoderStream == NULL)
    {
        ringfifo_log_error("HisiPutH264DataToBuffer: stream is NULL");
        return 0;
    }
    
    // 检查环形缓冲区是否已正确初始化
    if (!g_ring_buffer_initialized)
    {
        ringfifo_log_error("HisiPutH264DataToBuffer: Ring buffer not initialized! Call ringmalloc first");
        return 0;
    }
    
    if (encoderStream->pack == NULL)
    {
        ringfifo_log_error("HisiPutH264DataToBuffer: stream->pack is NULL");
        return 0;
    }
    
    if (encoderStream->packCount == 0 || encoderStream->packCount > 10)
    {
        ringfifo_log_error("HisiPutH264DataToBuffer: invalid packCount: %u", encoderStream->packCount);
        return 0;
    }
    
    // 2. 计算总数据长度并验证每个pack
    for (i = 0; i < encoderStream->packCount; i++)
    {
        // 更严格的virAddr检查，防止向NULL地址写入
        if (encoderStream->pack[i].virAddr == 0 || encoderStream->pack[i].virAddr == 0xFFFFFFFF)
        {
            ringfifo_log_error("HisiPutH264DataToBuffer: pack[%d].virAddr is invalid: 0x%08x", i, encoderStream->pack[i].virAddr);
            return 0;
        }
        
        if (encoderStream->pack[i].length == 0 || encoderStream->pack[i].length > 1024*1024)
        {
            ringfifo_log_error("HisiPutH264DataToBuffer: pack[%d].length is invalid: %u", i, encoderStream->pack[i].length);
            return 0;
        }
        
        // 防止整数溢出
        if (len > g_allocated_size - encoderStream->pack[i].length) {
            ringfifo_log_error("HisiPutH264DataToBuffer: potential integer overflow in length calculation");
            return 0;
        }
        
        len += encoderStream->pack[i].length;
    }
    
    // 丢弃过大的数据帧（超过1MB）
    if(len >= 1024*1024)
    {
        ringfifo_log_warning("drop data %d", len);
        return 1;
    }

    pthread_mutex_lock(&g_ring_mutex);

    // 检查缓冲区是否有空闲空间
    if(n < NMAX)
    {
        // 关键修复：检查当前写入位置的缓冲区是否已分配（防御性编程，防止NULL指针写入）
        if(ringfifo[iput].buffer == NULL)
        {
            ringfifo_log_error("HisiPutH264DataToBuffer: ringfifo[%d].buffer is NULL, ringmalloc not called or allocation failed", iput);
            pthread_mutex_unlock(&g_ring_mutex);
            return 0;
        }
        
        // 检查g_allocated_size是否有效（必须在ringmalloc之后）
        if (g_allocated_size <= 0)
        {
            ringfifo_log_error("HisiPutH264DataToBuffer: g_allocated_size is invalid (%d), ringmalloc not called or failed", g_allocated_size);
            pthread_mutex_unlock(&g_ring_mutex);
            return 0;
        }
        
        // 检查总长度是否超过缓冲区容量
        if (len > g_allocated_size)
        {
            ringfifo_log_error("HisiPutH264DataToBuffer: total length(%d) exceeds buffer capacity(%d)", len, g_allocated_size);
            pthread_mutex_unlock(&g_ring_mutex);
            return 0;
        }
        
        // 保存buffer指针，避免在循环中重复访问（防御性编程）
        unsigned char *target_buffer = ringfifo[iput].buffer;
        
        // 再次验证保存的指针是否有效
        if (target_buffer == NULL)
        {
            ringfifo_log_error("HisiPutH264DataToBuffer: target_buffer is NULL after assignment");
            pthread_mutex_unlock(&g_ring_mutex);
            return 0;
        }
        
        // 遍历所有数据包，拼接数据
        for (i = 0; i < encoderStream->packCount; i++)
        {
            // 再次验证源地址和长度（防御性编程，防止在循环中参数被修改）
            if (encoderStream->pack[i].virAddr == 0 || encoderStream->pack[i].virAddr == 0xFFFFFFFF)
            {
                ringfifo_log_error("HisiPutH264DataToBuffer: pack[%d].virAddr became invalid during processing: 0x%08x", i, encoderStream->pack[i].virAddr);
                pthread_mutex_unlock(&g_ring_mutex);
                return 0;
            }
            
            if (encoderStream->pack[i].length == 0 || encoderStream->pack[i].length > 1024*1024)
            {
                ringfifo_log_error("HisiPutH264DataToBuffer: pack[%d].length became invalid during processing: %u", i, encoderStream->pack[i].length);
                pthread_mutex_unlock(&g_ring_mutex);
                return 0;
            }
            
            // 检查写入是否会越界
            if (off + encoderStream->pack[i].length > g_allocated_size)
            {
                ringfifo_log_error("HisiPutH264DataToBuffer: write would exceed buffer boundary (off=%d, length=%u, capacity=%d)", 
                       off, encoderStream->pack[i].length, g_allocated_size);
                pthread_mutex_unlock(&g_ring_mutex);
                return 0;
            }
            
            // 增强的源地址指针验证 - 安全处理从uint32_t到void*的转换
            uint32_t virAddr = encoderStream->pack[i].virAddr;
            if (virAddr == 0 || virAddr == 0xFFFFFFFF)
            {
                ringfifo_log_error("HisiPutH264DataToBuffer: virAddr is invalid (0x%08x) for pack[%d]", virAddr, i);
                pthread_mutex_unlock(&g_ring_mutex);
                return 0;
            }
            
            // 安全转换uint32_t到void*
            void *src_ptr = (void *)(uintptr_t)virAddr;
            
            // 关键修复：双重检查src_ptr是否为NULL，防止向空指针写入
            if (src_ptr == NULL)
            {
                ringfifo_log_error("HisiPutH264DataToBuffer: src_ptr is NULL after conversion for pack[%d], virAddr=0x%08x", i, virAddr);
                pthread_mutex_unlock(&g_ring_mutex);
                return 0;
            }
            
            // 防止缓冲区溢出的最终检查
            if (target_buffer + off < target_buffer || target_buffer + off + encoderStream->pack[i].length > target_buffer + g_allocated_size)
            {
                ringfifo_log_error("HisiPutH264DataToBuffer: potential buffer overflow detected (off=%d, length=%u)", off, encoderStream->pack[i].length);
                pthread_mutex_unlock(&g_ring_mutex);
                return 0;
            }
            
            // 复制数据包到缓冲区
            memcpy(target_buffer + off, src_ptr, encoderStream->pack[i].length);
            
            // 更新偏移量
            off += encoderStream->pack[i].length;
            
            // 获取当前包的指针（用于NAL类型检查）
            unsigned char *pstr = (unsigned char *)src_ptr;

            // 增强的pstr指针检查
            if (pstr == NULL || pstr == 0)
            {
                ringfifo_log_error("HisiPutH264DataToBuffer: pstr is NULL for pack[%d]", i);
                continue; // 跳过这个包的NAL检查，但不中断整个处理
            }
            
            // 检查H.264 NAL类型（支持3字节和4字节起始码）
            int nal_type = 0;
            // 检查是否为4字节起始码 (0x00 0x00 0x00 0x01)
            if(encoderStream->pack[i].length >= 5 && 
               pstr[0] == 0x00 && pstr[1] == 0x00 && pstr[2] == 0x00 && pstr[3] == 0x01)
            {
                nal_type = pstr[4] & 0x1F; // 提取NAL类型（低5位）
            }
            // 检查是否为3字节起始码 (0x00 0x00 0x01)
            else if(encoderStream->pack[i].length >= 4 && 
                   pstr[0] == 0x00 && pstr[1] == 0x00 && pstr[2] == 0x01)
            {
                nal_type = pstr[3] & 0x1F; // 提取NAL类型（低5位）
            }

            // 检查是否为SPS数据（类型7，十六进制0x67）
            if(nal_type == 7)
            {
                // 标记为I帧
                iframe = 1;
                ringfifo_log_debug("Found SPS: nal_type=%d, length=%u", nal_type, encoderStream->pack[i].length);
                // 提取SPS数据（跳过起始码）
                unsigned char* sps_data = pstr;
                int sps_offset = 0;
                if(encoderStream->pack[i].length >= 5 && 
                   pstr[0] == 0x00 && pstr[1] == 0x00 && pstr[2] == 0x00 && pstr[3] == 0x01)
                {
                    sps_offset = 4;
                }
                else if(encoderStream->pack[i].length >= 4 && 
                       pstr[0] == 0x00 && pstr[1] == 0x00 && pstr[2] == 0x01)
                {
                    sps_offset = 3;
                }
                if(sps_offset > 0 && encoderStream->pack[i].length > sps_offset)
                {
                    // 调用update_video_params更新SPS
                    extern void update_video_params(unsigned char* spsData, size_t spsSize, 
                                                    unsigned char* ppsData, size_t ppsSize);
                    update_video_params(sps_data + sps_offset, encoderStream->pack[i].length - sps_offset, 
                                       NULL, 0);
                    ringfifo_log_debug("Updated SPS parameters: size=%u", encoderStream->pack[i].length - sps_offset);
                }
            }
            // 检查是否为PPS数据（类型8，十六进制0x68）
            if(nal_type == 8)
            {
                ringfifo_log_debug("Found PPS: nal_type=%d, length=%u", nal_type, encoderStream->pack[i].length);
                // 提取PPS数据（跳过起始码）
                unsigned char* pps_data = pstr;
                int pps_offset = 0;
                if(encoderStream->pack[i].length >= 5 && 
                   pstr[0] == 0x00 && pstr[1] == 0x00 && pstr[2] == 0x00 && pstr[3] == 0x01)
                {
                    pps_offset = 4;
                }
                else if(encoderStream->pack[i].length >= 4 && 
                       pstr[0] == 0x00 && pstr[1] == 0x00 && pstr[2] == 0x01)
                {
                    pps_offset = 3;
                }
                if(pps_offset > 0 && encoderStream->pack[i].length > pps_offset)
                {
                    // 调用update_video_params更新PPS
                    extern void update_video_params(unsigned char* spsData, size_t spsSize, 
                                                    unsigned char* ppsData, size_t ppsSize);
                    // 注意：这里只更新PPS，SPS应该已经在之前更新过了
                    update_video_params(NULL, 0, pps_data + pps_offset, encoderStream->pack[i].length - pps_offset);
                    ringfifo_log_debug("Updated PPS parameters: size=%u", encoderStream->pack[i].length - pps_offset);
                }
            }
        }

        // 设置缓冲区大小
        ringfifo[iput].size = len;
        // 设置帧类型
        ringfifo[iput].frame_type = iframe;
        // 更新写入位置到下一个
        iput = addring(iput);
        // 增加帧计数器
        n++;
    }

    pthread_mutex_unlock(&g_ring_mutex);
    return 1; // 返回成功
}
